import { combineResolvers } from 'graphql-resolvers'
import { pageModel } from '../../lib/helper'
import auth from '../../middlewares/auth'
import { userLoader } from '../user/dataloaders'
import { taskLoader } from '../task/dataloaders'
import { documentLoader } from '../document/dataloaders'
import { answerLoader } from '../answer/dataloaders'
import dayjs from 'dayjs'
import fdb from '../../lib/fdb'
import CONFIG from '../../config'
import axios from 'axios'

module.exports = {
  Query: {
    progress: async (root, { id }, { models: { Progress } }) => {
      const result = await Progress.findById(id)
      return result
    },
    userProgresses: combineResolvers(
      auth,
      async (
        root,
        { pageIndex, pageSize },
        { services: { $progress }, user }
      ) => {
        let userId = user.id
        const result = await $progress.findAllUserProgresses(
          userId,
          pageIndex,
          pageSize
        )

        let rows = result.rows
        let acids = rows.map(n => {
          return `${n.documentId}_${n.groupId}`
        })
        if (acids.length) {
          try {
            let apiUrl = `${CONFIG.app.contentServerApi}/v1/assignments/${acids.join(',')}/submissions/status?studentId=${user.id}`
            let res = await axios({
              method: 'get',
              url: apiUrl,
              headers: {
                'Authorization': 'Bearer 1EB39DDA-CA30-458F-9E13-BDE9CE2B5A12'
              }
            })
            if (res.data.statuses && res.data.statuses.length) {
              let kv = {}
              res.data.statuses.forEach(n => {
                kv[`${n.assignmentId}_${n.classId}`] = n
              })
              for (let i = 0; i < rows.length; i++) {
                let r = rows[i]
                let s = kv[`${r.documentId}_${r.groupId}`]
                if (!s) continue
                r.teacherCheckedStatus = s.teacherCheckedStatus || ''
                r.exerciseStatus = s.status || ''
                r.submissionId = s.submissionId || 0
                r.assignmentId = s.assignmentId || 0
                r.classId = s.classId || 0
                rows[i] = r
              }
              result.rows = rows
            }
          } catch (e) {
            console.error(e)
          }
        }
        return pageModel(result, pageIndex, pageSize)
      }
    ),
    progressGetMyUnreadCount: combineResolvers(
      auth,
      async (
        root,
        data,
        { models: { Progress }, user }
      ) => {
        let t = await fdb.findOne({
          tbl: 'progresses',
          attrs: [
            'count(id) as totalUnreadCount'
          ],
          where: [
            'userId=' + user.id,
            'unreadCount=-1'
          ]
        })
        if (!t) return 0
        if (!t.totalUnreadCount) return 0
        return t.totalUnreadCount
      }
    )
  },
  Mutation: {
    createDocumentProgress: combineResolvers(
      auth,
      async (
        root,
        { documentId, groupId, distributeAt },
        { services: { $progress }, user }
      ) => {
        let userId = user.id
        console.info(
          `create or find progress with documentId:${documentId} userId:${userId} groupId:${groupId}`
        )
        return await $progress.findOrCreateWithDocument(
          documentId,
          userId,
          groupId,
          distributeAt
        )
      }
    ),
    createProgress: combineResolvers(
      auth,
      async (root, { taskId }, { services: { $progress }, user }) => {
        let userId = user.id
        console.info(`create progress for task:${taskId} user:${userId}`)
        return await $progress.findOrCreateWithTask(taskId, userId)
      }
    ),
    createProgressByAgid: combineResolvers(
      auth,
      async (root, { agid }, { models: {Task}, services: { $progress }, user }) => {
        let t = agid.split('_')
        let documentId = t[0]
        let groupId = t[1]
        if (!documentId || !groupId) throw new Error('params error!')
        let task = await Task.findOne({
          where: {
            documentId,
            groupId
          }
        })
        if (!task) throw new Error('task not found!')
        let userId = user.id
        return await $progress.findOrCreateWithTask(task.id, userId)
      }
    ),
    readProgress: combineResolvers(
      auth,
      async (root, { progressId }, { services: { $progress }, user }) => {
        let userId = user.id
        console.info(
          `read progress to reset unread numbers progressId:${progressId} user:${userId}`
        )
        return await $progress.readProgress(progressId, userId)
      }
    )
  },
  Progress: {
    user: ({ userId }, data, { dataloaders: { userLoader } }) => {
      return userLoader.load(userId)
    },
    member: async ({ groupId, userId }, data, { dataloaders: { memberLoader } }) => {
      let member = await fdb.findOne({
        tbl: 'user_group as ug',
        joins: [
          'left join users as u on u.id = ug.userId'
        ],
        attrs: [
          'ug.*, u.nickName, u.avatarUrl, u.gender'
        ],
        where: [
          `ug.groupId=${groupId}`,
          `ug.userId=${userId}`
        ],
        orders: [
          `createdAt desc`
        ]
      })
      return member
      // return memberLoader.load([groupId, userId].join('_'))
    },
    stateName: ({ state }) => {
      let stateName = ''
      if (state === 'start') {
        stateName = '未交'
      } else if (state === 'done') {
        stateName = '待评'
      } else if (state === 'check') {
        stateName = '已评'
      } else if (state === 'redo') {
        stateName = '重做'
      }
      return stateName
    },
    task: ({ taskId }, data, { dataloaders: { taskLoader } }) => {
      return taskLoader.load(taskId)
    },
    isExpired: ({ state, expireAt }, data) => {
      if (state != 'start') return false
      if (!expireAt) return false
      let flag = dayjs().isAfter(dayjs(expireAt))
      return flag
    },
    creator: ({ userId }, data, { dataloaders: { userLoader } }) => {
      return userLoader.load(userId)
    },
    document: ({ versionId }, data, { dataloaders: { documentLoader } }) => {
      return documentLoader.load(versionId)
    },
    answers: ({ id }, data, { dataloaders: { answerLoaderByProgress } }) => {
      return answerLoaderByProgress.load(id)
    },
    liked: ({ id }, data, { dataloaders: { likedLoaderByProgress } }) => {
      return likedLoaderByProgress.load(id)
    }
  }
}
